import { onUnmounted } from 'vue'
import createFetch from './createFetch'
import type { Options, Service, FetchResult, FunctionPlugin } from './types'

function useFetch<Data, P extends unknown[]>(
  service: Service<Data, P>,
  options: Options<Data, P> = {},
  plugins: FunctionPlugin<Data, P>[]
): FetchResult<Data, P> {
  const config = { ...options }

  const { manual = false, defaultParams = [] as P } = config

  const fetchInstance = createFetch(service, config)

  fetchInstance.plugins.value = plugins.map(plugin => plugin(fetchInstance, config))

  // 自动执行
  if (!manual) {
    const params = fetchInstance.params.value || defaultParams
    fetchInstance.context.run(...params)
  }

  onUnmounted(() => {
    fetchInstance.context.cancel()
  })

  return {
    loading: fetchInstance.loading,
    data: fetchInstance.data,
    error: fetchInstance.error,
    params: fetchInstance.params,
    cancel: fetchInstance.context.cancel,
    refresh: fetchInstance.context.refresh,
    refreshAsync: fetchInstance.context.refreshAsync,
    mutate: fetchInstance.context.mutate,
    run: fetchInstance.context.run,
    runAsync: fetchInstance.context.runAsync
  }
}

export default useFetch
